"use client";

import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import {
  hasQuestionAnswerValue,
  QuestionAnswersProvider,
  useQuestionAnswers,
} from "@/components/questions/question-answer-storage";
import QuestionExitNavigationButton from "@/components/questions/question-exit-navigation-button";
import QuestionRenderer from "@/components/questions/question-renderer";
import QuestionSectionFlow from "@/components/questions/question-section-flow";
import TestIntroPage from "@/components/questions/test-intro-page";
import TestQuestionsFlow, {
  type TestQuestion,
} from "@/components/questions/test-questions-flow";
import { DotsLoader } from "@/components/ui/button";
import NavigationButton from "@/components/ui/navigation-button";
import StickyHeader from "@/components/ui/sticky-header";
import { PageBackground } from "@/components/utils/page-background";
import { cattellFallbackQuestions } from "@/data/cattell-fallback";
import { glasserFallbackQuestions } from "@/data/glasser-fallback";
import {
  getQuestionListItemBySlug,
  isQuestionListItemVisibleForProfile,
  isQuestionRequiredForProfile,
  isQuestionVisibleForProfile,
  type QuestionField,
} from "@/data/question-data";
import type { MarriageGender } from "@/hooks/marriage/types";
import {
  useCattellQuestionsQuery,
  useSubmitCattellAssessmentMutation,
} from "@/hooks/marriage/use-cattell";
import {
  useGlasserQuestionsQuery,
  useSubmitGlasserAssessmentMutation,
} from "@/hooks/marriage/use-glasser";
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
import { defaultLocale, type Locale } from "@/translations/config";
import { useI18n } from "@/translations/provider";
import AnswerPaceSheet from "./answer-pace-sheet";

type QuestionDetailClientProps = {
  closeLabel: string;
  continueLabel: string;
  description: string;
  informationLabel: string;
  itemSlug: string;
  locale?: Locale;
  questionsListHref: string;
  title: string;
};

type StoredQuestionField = {
  label?: string;
  value?: unknown;
  type?: string;
  key?: string;
};

type StoredAnswers = {
  fields?: StoredQuestionField[];
};

function getQuestionStorageKey(slug: string) {
  return `marriage:sections:${slug}:answers`;
}

function parseStoredAge(value: unknown) {
  if (typeof value === "number" && Number.isFinite(value)) {
    return value;
  }

  if (typeof value === "string") {
    const trimmedValue = value.trim();

    if (!trimmedValue) {
      return null;
    }

    const numericAge = Number(trimmedValue);

    if (Number.isFinite(numericAge)) {
      return numericAge;
    }

    const dateOfBirth = new Date(trimmedValue);

    if (Number.isNaN(dateOfBirth.getTime())) {
      return null;
    }

    const today = new Date();
    let age = today.getFullYear() - dateOfBirth.getFullYear();
    const hasBirthdayPassed =
      today.getMonth() > dateOfBirth.getMonth() ||
      (today.getMonth() === dateOfBirth.getMonth() &&
        today.getDate() >= dateOfBirth.getDate());

    if (!hasBirthdayPassed) {
      age -= 1;
    }

    return age >= 0 ? age : null;
  }

  return null;
}

function getStoredAge() {
  try {
    const rawValue = window.localStorage.getItem(
      getQuestionStorageKey("personal_info"),
    );

    if (!rawValue) {
      return null;
    }

    const storedAnswers = JSON.parse(rawValue) as StoredAnswers;
    const ageField = storedAnswers.fields?.find(
      (field) =>
        field.type === "number" ||
        field.label === "Age" ||
        field.label === "سن" ||
        (typeof (field as any).key === "string" &&
          ((field as any).key.endsWith("_age") ||
            (field as any).key.endsWith("_sn"))),
    );

    if (ageField) {
      return parseStoredAge(ageField.value);
    }

    const dateOfBirthField = storedAnswers.fields?.find(
      (field) =>
        field.type === "date" ||
        field.label === "Date of Birth" ||
        field.label === "تاریخ تولد" ||
        (typeof (field as any).key === "string" &&
          ((field as any).key.endsWith("_date_of_birth") ||
            (field as any).key.endsWith("_tarykh_twld"))),
    );

    return parseStoredAge(dateOfBirthField?.value);
  } catch {
    return null;
  }
}

function QuestionFlowWrapper({
  visibleQuestions,
  itemSlug,
  dobQuestion,
  dobQuestionIndex,
  continueLabel,
  questionsListHref,
}: {
  visibleQuestions: QuestionField[];
  itemSlug: string;
  dobQuestion?: QuestionField;
  dobQuestionIndex?: number;
  requiredQuestionsCount: number;
  continueLabel: string;
  questionsListHref: string;
}) {
  const { getAnswerValue } = useQuestionAnswers();

  const dynamicQuestions = useMemo(() => {
    return visibleQuestions.filter((question) => {
      if (question.logic?.dependsOn) {
        const { title, values } = question.logic.dependsOn;
        const dependentQuestionIndex = visibleQuestions.findIndex(
          (q) => q.title === title,
        );

        if (dependentQuestionIndex !== -1) {
          const dependentQuestion = visibleQuestions[dependentQuestionIndex];
          const answer = getAnswerValue(
            dependentQuestion,
            dependentQuestionIndex,
          );
          return values.includes(String(answer));
        }
        return false;
      }
      return true;
    });
  }, [visibleQuestions, getAnswerValue]);

  const requiredCount = useMemo(
    () => dynamicQuestions.filter((q) => q.required).length,
    [dynamicQuestions],
  );

  return (
    <QuestionSectionFlow
      key={itemSlug}
      total={requiredCount}
      continueLabel={continueLabel}
      exitHref={questionsListHref}
      optionalQuestionIndexes={dynamicQuestions.flatMap((question, index) =>
        question.required ? [] : [index],
      )}
      questions={dynamicQuestions}
    >
      {dynamicQuestions.map((question, index) => {
        const originalIndex = visibleQuestions.indexOf(question);
        const answer = getAnswerValue(question, originalIndex);
        const hasAnswer = hasQuestionAnswerValue(answer ?? null);
        let isAnswered = hasAnswer;

        if (hasAnswer) {
          const isEmailQuestion =
            question.title.toLowerCase().includes("email") ||
            question.title.includes("ایمیل");
          if (isEmailQuestion) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            isAnswered = emailRegex.test(String(answer).trim());
          } else if (question.type === "birthplace") {
            const strVal = String(answer);
            const parts = strVal.split(",").map((p) => p.trim());
            isAnswered =
              parts.length >= 2 && parts[0].length > 0 && parts[1].length > 0;
          }
        }

        return (
          <div
            key={`${itemSlug}-${question.title}`}
            data-question-required={String(question.required)}
            data-question-optional={String(!question.required)}
            data-question-index={index}
            data-question-original-index={originalIndex}
            data-question-disabled="false"
            data-question-answered={String(isAnswered)}
          >
            <QuestionRenderer
              question={question}
              questionIndex={originalIndex}
              dobQuestion={dobQuestion}
              dobQuestionIndex={dobQuestionIndex}
            />
          </div>
        );
      })}
    </QuestionSectionFlow>
  );
}

export default function QuestionDetailClient({
  closeLabel,
  continueLabel,
  description,
  informationLabel,
  itemSlug,
  locale = defaultLocale,
  questionsListHref,
  title,
}: QuestionDetailClientProps) {
  const router = useRouter();
  const { dictionary: t } = useI18n();
  const [isTestStarted, setIsTestStarted] = useState(false);
  const { data: profile, isLoading: isProfileLoading } =
    useMarriageProfileQuery();
  const profileGender = profile?.gender;
  const age = getStoredAge();
  const item = getQuestionListItemBySlug(itemSlug, locale);

  const isCattellSlug = itemSlug === "personality_test";
  const isGlasserSlug = itemSlug === "glasser_5_needs_test";

  const cattellQuery = useCattellQuestionsQuery(locale, {
    enabled: isCattellSlug && isTestStarted,
    retry: 0,
  });
  const submitCattellMutation = useSubmitCattellAssessmentMutation();

  const glasserQuery = useGlasserQuestionsQuery(locale, {
    enabled: isGlasserSlug && isTestStarted,
    retry: 0,
  });
  const submitGlasserMutation = useSubmitGlasserAssessmentMutation();

  const profileContext = useMemo(
    () => ({
      age,
      gender: profileGender as MarriageGender | null | undefined,
    }),
    [age, profileGender],
  );

  const cattellTestQuestions: TestQuestion[] = useMemo(() => {
    const questionsList =
      cattellQuery.data?.questions && cattellQuery.data.questions.length > 0
        ? cattellQuery.data.questions
        : cattellFallbackQuestions;

    return questionsList.map((q) => {
      const rawOptions =
        q.options && q.options.length > 0
          ? q.options
          : locale === "fa"
            ? ["بله", "به اندازه کافی واضح نیست", "نه"]
            : ["Yes", "Not clear enough", "No"];
      const mappedOptions = rawOptions.map((optText, idx) => ({
        label: optText,
        value: idx === 0 ? "A" : idx === 1 ? "B" : "C",
      }));
      return {
        id: q.question_number,
        text: q.text,
        options: mappedOptions,
      };
    });
  }, [cattellQuery.data]);

  const glasserTestQuestions: TestQuestion[] = useMemo(() => {
    const questionsList =
      glasserQuery.data?.questions && glasserQuery.data.questions.length > 0
        ? glasserQuery.data.questions
        : glasserFallbackQuestions;

    const defaultGlasserOptions = [
      { label: locale === "fa" ? "خیلی کم (۱)" : "Very Low (1)", value: 1 },
      { label: locale === "fa" ? "کم (۲)" : "Low (2)", value: 2 },
      { label: locale === "fa" ? "متوسط (۳)" : "Moderate (3)", value: 3 },
      { label: locale === "fa" ? "زیاد (۴)" : "High (4)", value: 4 },
      { label: locale === "fa" ? "خیلی زیاد (۵)" : "Very High (5)", value: 5 },
    ];

    return questionsList.map((q) => ({
      id: q.question_number,
      text: q.text,
      info:
        "factor" in q
          ? (q.factor as string)
          : "factor_code" in q
            ? (q.factor_code as string)
            : undefined,
      options: defaultGlasserOptions,
    }));
  }, [glasserQuery.data, locale]);

  const visibleQuestions = useMemo(() => {
    if (!item) {
      return [];
    }

    const hasDobQuestion = item.questions.some(
      (q) => q.title === "Date of Birth" || q.title === "تاریخ تولد",
    );

    return item.questions
      .filter((question) => {
        if (
          hasDobQuestion &&
          (question.title === "Age" || question.title === "سن")
        ) {
          return false;
        }
        return isQuestionVisibleForProfile(question, profileContext);
      })
      .map((question) => ({
        ...question,
        required: isQuestionRequiredForProfile(question, profileContext),
      }));
  }, [item, profileContext]);

  const requiredQuestionsCount = useMemo(
    () => visibleQuestions.filter((q) => q.required).length,
    [visibleQuestions],
  );

  useEffect(() => {
    if (isProfileLoading) {
      return;
    }

    if (!item || isQuestionListItemVisibleForProfile(item, profileContext)) {
      return;
    }

    router.replace(questionsListHref);
  }, [isProfileLoading, item, profileContext, questionsListHref, router]);

  if (isProfileLoading && item) {
    return (
      <>
        <PageBackground disabled />
        <main className="-mx-[17px] flex h-svh flex-col items-center justify-center bg-[#F7F1F0]">
          <DotsLoader className="text-[#F2465F] scale-150" />
        </main>
      </>
    );
  } else if (
    !item ||
    !isQuestionListItemVisibleForProfile(item, profileContext)
  ) {
    return null;
  }

  if (item && item.questions.length === 0) {
    if (isTestStarted) {
      const isQuestionsLoading = isCattellSlug
        ? cattellQuery.isLoading || cattellQuery.isFetching
        : isGlasserSlug
          ? glasserQuery.isLoading || glasserQuery.isFetching
          : false;

      if (isQuestionsLoading) {
        return (
          <>
            <PageBackground disabled />
            <main className="-mx-[17px] flex h-svh flex-col items-center justify-center bg-[#F7F1F0]">
              <DotsLoader className="text-[#F2465F] scale-150" />
            </main>
          </>
        );
      }

      const activeTestQuestions = isCattellSlug
        ? cattellTestQuestions
        : isGlasserSlug
          ? glasserTestQuestions
          : [];

      if (activeTestQuestions.length === 0) {
        const isError = isCattellSlug
          ? cattellQuery.isError
          : isGlasserSlug
            ? glasserQuery.isError
            : false;
        const refetch = isCattellSlug
          ? cattellQuery.refetch
          : glasserQuery.refetch;

        return (
          <>
            <PageBackground disabled />
            <main className="-mx-[17px] flex h-svh flex-col items-center justify-center gap-4 bg-[#F7F1F0] px-6 text-center">
              <p className="font-semibold text-[#1B1B1B]">
                {isError
                  ? locale === "fa"
                    ? "خطا در دریافت سوالات از سرور. لطفاً از اتصال اینترنت یا ورود به حساب کاربری اطمینان حاصل کنید."
                    : "Failed to load questions from server. Please check your connection or login status."
                  : locale === "fa"
                    ? "سوالاتی برای این آزمون یافت نشد."
                    : "No questions found for this test."}
              </p>
              <div className="flex gap-3">
                <button
                  type="button"
                  onClick={() => setIsTestStarted(false)}
                  className="rounded-xl bg-[#EFEFEF] px-4 py-2 text-sm font-semibold text-[#1B1B1B]"
                >
                  {closeLabel}
                </button>
                <button
                  type="button"
                  onClick={() => refetch()}
                  className="rounded-xl bg-[#F2465F] px-4 py-2 text-sm font-semibold text-white shadow-md"
                >
                  {locale === "fa" ? "تلاش مجدد" : "Retry"}
                </button>
              </div>
            </main>
          </>
        );
      }

      const handleTestFinish = async (
        answers: Record<number, string | number>,
      ) => {
        if (isCattellSlug) {
          const responses = Object.entries(answers).map(([qNum, option]) => ({
            question_number: Number(qNum),
            option: String(option),
          }));
          try {
            await submitCattellMutation.mutateAsync({ responses });
          } catch {
            // Ignore if already submitted or API returned error
          }
          try {
            window.localStorage.setItem(
              getQuestionStorageKey(item.slug),
              JSON.stringify({ completed: true }),
            );
          } catch {}
        } else if (isGlasserSlug) {
          const responses = Object.entries(answers).map(([qNum, score]) => ({
            question_number: Number(qNum),
            score: Number(score),
          }));
          try {
            await submitGlasserMutation.mutateAsync({ responses });
          } catch {
            // Ignore if already submitted
          }
          try {
            window.localStorage.setItem(
              getQuestionStorageKey(item.slug),
              JSON.stringify({ completed: true }),
            );
          } catch {}
        }
        await new Promise((resolve) => setTimeout(resolve, 1200));
      };

      return (
        <TestQuestionsFlow
          title={item.title}
          questions={activeTestQuestions}
          closeLabel={closeLabel}
          informationLabel={informationLabel}
          onClose={() => setIsTestStarted(false)}
          onFinish={handleTestFinish}
        />
      );
    }

    const bulletKey =
      item.slug === "glasser_5_needs_test" ? "glasser" : "personality";
    const bullets = t.questions.testIntroBullets[bulletKey];

    return (
      <>
        <PageBackground disabled />
        <main className="-mx-[17px] flex h-svh flex-col overflow-hidden bg-[#F7F1F0]">
          <StickyHeader sticky={false} className="shrink-0">
            <div className="flex items-center gap-4">
              <NavigationButton
                className="shrink-0"
                variant="transparent"
                icon="close"
                iconLabel={closeLabel}
              />
              <h1 className="min-w-0 flex-1 text-center text-[14px] font-semibold text-white truncate">
                {item.title}
              </h1>
              <NavigationButton
                className="shrink-0"
                variant="transparent"
                icon="info"
                iconLabel={informationLabel}
                helpTitle={item.title}
                helpDescription={description}
              />
            </div>
          </StickyHeader>

          <div className="mx-auto flex w-full max-w-md flex-1 flex-col px-[17px] pt-3 min-h-0">
            <TestIntroPage
              title={item.title}
              estimateTime={item.estimate}
              description={t.questions.testIntroEstimateLabel}
              bulletPoints={bullets}
              disclaimerText={t.questions.testIntroDisclaimer}
              startLabel={t.questions.testIntroStart}
              onStart={() => {
                setIsTestStarted(true);
              }}
            />
          </div>
        </main>
      </>
    );
  }

  const dobQuestion = visibleQuestions.find(
    (question) => question.title === "Date of Birth",
  );
  const dobQuestionIndex = visibleQuestions.findIndex(
    (question) => question.title === "Date of Birth",
  );

  return (
    <>
      <PageBackground disabled />
      <AnswerPaceSheet
        slug={item.slug}
        title={title}
        description={description}
        continueLabel={continueLabel}
      />

      <QuestionAnswersProvider slug={item.slug} questions={visibleQuestions}>
        <main className="-mx-[17px] flex h-svh flex-col overflow-hidden bg-[#F7F1F0]">
          <StickyHeader sticky={false} className="shrink-0">
            <div className="flex items-center gap-4">
              <QuestionExitNavigationButton
                className="shrink-0"
                variant="transparent"
                icon="close"
                iconLabel={closeLabel}
                exitHref={questionsListHref}
              />
              <h1 className="min-w-0 flex-1 text-center text-[14px] font-semibold text-white truncate">
                {item.title}
              </h1>
              <NavigationButton
                className="shrink-0"
                variant="transparent"
                icon="info"
                iconLabel={informationLabel}
                helpTitle={item.title}
                helpDescription={description}
              />
            </div>
          </StickyHeader>

          <div className="mx-auto flex w-full max-w-md flex-1 flex-col px-[17px] pt-3 min-h-0">
            <QuestionFlowWrapper
              visibleQuestions={visibleQuestions}
              itemSlug={item.slug}
              dobQuestion={dobQuestion}
              dobQuestionIndex={dobQuestionIndex}
              requiredQuestionsCount={requiredQuestionsCount}
              continueLabel={continueLabel}
              questionsListHref={questionsListHref}
            />
          </div>
        </main>
      </QuestionAnswersProvider>
    </>
  );
}
